import Icon from '@/components/Icon';
import NavBar from '@/components/NavBar';
import { useAppSelector } from '@/store';
import {
  clearHistoriesAction,
  clearSuggestAction,
  getSearchAction,
  saveHistoriesAction,
} from '@/store/action/search';
// import classnames from 'classnames';
import { useEffect, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import styles from './index.module.scss';
import DOMPurify from 'dompurify';
import { setLocalHistories } from '@/utils/storage';
import { Toast } from 'antd-mobile';
import { useHistory } from 'react-router-dom';

// 1. 创建替换关键字的函数
const lighHight = (str: string, keyword: string) => {
  const reg = new RegExp(`(${keyword})`, 'gi');
  return str.replace(reg, '<span>$1</span>');
};
export default function Search() {
  const history = useHistory();
  const dispatch = useDispatch();
  // 使用ref存储timeId
  const timeIdRef = useRef(0);
  // 2.1 声明状态
  const [keyword, setKeyword] = useState('');
  const { suggest, histories } = useAppSelector((state) => state.search);
  const handelSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value.trim();

    // 3.2 非空才更新界面，非空才发送请求
    setKeyword(value);
    // 防抖写法
    // 先清除上次的定时器
    clearTimeout(timeIdRef.current);
    // 清空值之后，让界面更新和清除定时器之后，再阻止往下执行
    if (!value) {
      dispatch(clearSuggestAction());
      return;
    }
    // 再重新开启新的定时器\
    timeIdRef.current = window.setTimeout(() => {
      console.log('  ----->  ', e.target.value);
      dispatch(getSearchAction(value));
    }, 500);
  };
  // 2. 监听变化
  useEffect(() => {
    setLocalHistories(histories);
  }, [histories]);

  // 搜索事件
  const handelSearchHistory = () => {
    if (!keyword) {
      Toast.show({ content: '搜索结果不能为空' });
    }
    dispatch(saveHistoriesAction(keyword));
    // 使用history.push传递查询字符串参数
    history.push({
      pathname: '/search/result',
      // search会都自动将字符串拼接到?后面
      search: `q=${keyword}`,
    });
  };
  // 键盘事件
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handelSearchHistory();
    }
  };
  // 清空键盘事件
  const handleClearKeyCode = () => {
    setKeyword('');
  };
  // 清除搜索建议
  useEffect(() => {
    if (!keyword) {
      dispatch(clearSuggestAction());
    }
  }, [keyword, dispatch]);
  useEffect(() => {
    return () => {
      dispatch(clearSuggestAction());
    };
  }, [dispatch]);

  return (
    <div className={styles.root}>
      {/* 顶部导航栏 */}
      <NavBar
        right={
          <span
            className="search-text"
            onClick={handelSearchHistory}
            onKeyDown={(e) => handleKeyDown}
          >
            搜索
          </span>
        }
      >
        <div className="navbar-search">
          <Icon type="iconbtn_search" className="icon-search" />

          <div className="input-wrapper">
            {/* 输入框 */}
            <input
              type="text"
              placeholder="请输入关键字搜索"
              onChange={handelSearch}
              value={keyword}
            />

            {/* 清空输入框按钮 */}
            <Icon
              type="iconbtn_tag_close"
              className="icon-close"
              onClick={handleClearKeyCode}
            />
          </div>
        </div>
      </NavBar>

      {/* 搜索历史 */}
      {!keyword ? (
        <div className="history" style={{ display: 'block' }}>
          <div className="history-header">
            <span>搜索历史</span>
            <span onClick={() => dispatch(clearHistoriesAction())}>
              <Icon type="iconbtn_del" />
            </span>
          </div>
          <div className="history-list">
            {histories.map((item) => {
              return (
                <span className="history-item" key={item}>
                  {item}
                  <span className="divider"></span>
                </span>
              );
            })}
          </div>
        </div>
      ) : (
        <div className="search-result">
          {suggest.map((item, index) => {
            return (
              <div className="result-item" key={index}>
                <Icon className="icon-search" type="iconbtn_search" />
                <div
                  className="result-value"
                  // 类似vue中v-html
                  // React中不能同时使用dangerouslySetInnerHTML和插槽同时使用
                  dangerouslySetInnerHTML={{
                    // __html是固定的写法
                    __html: DOMPurify.sanitize(lighHight(item, keyword)),
                  }}
                ></div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
